package com.yeban.bams.server.manager;

import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Desc 登录管理类
 * @Author yeban
 * @Date 2025/11/9
 */
public class LoginManager {

    // static：保证全局类中使用，final：保证唯一实例，可以添加删除其中的元素
    private static final ConcurrentHashMap<Long, LoginInfo> loginMap = new ConcurrentHashMap<>();

    private static Runnable listener;

    public static void setListener(Runnable l) {
        listener = l;
    }

    private static void notifyListener() {
        if (listener != null) listener.run();
    }

    /**
     * 判断是否允许登录：
     * 1. 同一 IP 可登录多个账户
     * 2. 同一账户不可在任意 IP 重复登录
     * @param socket
     * @param accId
     * @return
     */
    public static synchronized boolean loginValid(Socket socket, Long accId) {
        // 同一账户不可重复登录；同一 IP 可登录多个不同账户
        String ip = socket.getInetAddress().getHostAddress();
        if (loginMap.containsKey(accId)) {
            System.out.println("账户：" + accId + "已在" + loginMap.get(accId).getIp() + "中登录了！\n请关闭账户后重试！");
            return false;
        }
        LoginInfo loginInfo = new LoginInfo(ip, accId);
        loginMap.put(accId, loginInfo);
        System.out.println(accId + "在" + ip + "中登录成功！");
        notifyListener(); // 通知 RankPanel 刷新
        return true;
    }

    /**
     * 注册后自动登记登录（无验证）
     */
    public static synchronized void registerLogin(Socket socket, Long accId) {
        String ip = socket.getInetAddress().getHostAddress();
        LoginInfo info = new LoginInfo(ip, accId);
        loginMap.put(accId, info);
        System.out.println("注册并登录：" + info);
        notifyListener(); // 通知 RankPanel 刷新
    }

    /**
     * 客户端断开时自动登出
     */
    public static void unLoginValid(Socket socket) {
        String ip = socket.getInetAddress().getHostAddress();
        // 根据ip找到对应账户
        loginMap.entrySet().removeIf(entry -> entry.getValue().getIp().equals(ip));
        System.out.println("ip：" + ip + "已登出！");
        notifyListener(); // 通知 RankPanel 刷新
    }

    // 查看某个账户是否登录
    public static boolean isLoggedIn(Long accId) {
        return loginMap.containsKey(accId);
    }

    /**
     * 获取当前所有登录状态（副本）
     */
    public static ConcurrentHashMap<Long, LoginInfo> getLoginMap() {
        return new ConcurrentHashMap<>(loginMap);
    }

    // 显式登出（按账户）
    public static synchronized void logout(Long accId) {
        if (loginMap.remove(accId) != null) {
            System.out.println("账户：" + accId + "已登出！");
            notifyListener(); // 通知 RankPanel 刷新
        }
    }
}
